package com.wtp.wallpaper.utils;

import com.wtp.wallpaper.common.constant.MessageConstant;
import com.wtp.wallpaper.common.exception.PictureExpireException;
import net.coobird.thumbnailator.Thumbnails;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Comparator;

public class PictureReduceUtil {

    //转化一张图片
    public static void convert(String inPath,String outPath){
        convert(new File(inPath),outPath);
    }

    public static void convert(File file,String outPath){

        if(!file.exists() || file.isDirectory()){
            throw new PictureExpireException(MessageConstant.PICTURE_EXPIRE);
        }
        checkPath(outPath);

        try {
            Thumbnails.of(file)
                    .scale(getFloat(file))
                    .outputFormat(getSuffix(file.getName()))
                    .toFile(outPath + "/" + file.getName());
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    //递归转换文件夹下所有图片
    public static void recursion(String inPath,String outPath) {
        process(new File(inPath).listFiles(),outPath);
    }

    //递归缩略图片
    private static void process(File[] files,String outputPath){

        if(files == null) return;

        for (File file : files) {
            if (file.isDirectory()){
                process(file.listFiles(),outputPath + "/" + file.getName());
                continue;
            }

            convert(file,outputPath);
        }

    }

    //缩略精度
    private static double getFloat(File file){


        double org = file.length() * 1.0 / 1024 / 1024;
        if(org < 0.3){
            return 1;
        }
        if(org >= 0.3 && org <= 1){
            return 0.8;
        }
        if(org > 1 && org <= 2){
            return 0.6;
        }
        if(getSuffix(file.getName()).equals("png")){
            return 0.1;
        }
        return 0.3;
    }

    //获取文件后缀
    public static String getSuffix(String pic){
        return pic.substring(pic.lastIndexOf(".") + 1);
    }

    //检查文件路径是否存在 不存在就创建
    public static void checkPath(String filePath){
        if(!new File(filePath).exists()){
            createDir(filePath);
        }
    }

    //创建文件夹
    public static void createDir(String filePath){

        File file;
        String[] split = filePath.split("/");
        StringBuffer sb = new StringBuffer();
        for(String s : split){
            sb.append("//");
            sb.append(s);
            file = new File(sb.toString());
            if(!file.exists()){
                file.mkdir();
            }
        }
    }

    public static String calculateMD5(MultipartFile file) {
        String res = "";
        try(InputStream in = file.getInputStream()){
            res = calculateMD5(in);
        }catch (IOException e) {
            throw new RuntimeException("MD5计算失败", e);
        }
        return res;
    }

    public static String calculateMD5(Path inPath) {
        String res = "";
        try(InputStream in = Files.newInputStream(inPath)){
            res = calculateMD5(in);
        }catch (IOException e) {
            throw new RuntimeException("MD5计算失败", e);
        }
        return res;
    }

    /*public static String calculateMD5(MultipartFile file) {
        try (InputStream is = file.getInputStream()) {
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] buffer = new byte[8192];
            int read;
            while ((read = is.read(buffer)) != -1) {
                md.update(buffer, 0, read);
            }
            byte[] hashBytes = md.digest();
            StringBuilder sb = new StringBuilder();
            for (byte b : hashBytes) {
                sb.append(String.format("%02x", b & 0xFF));  // 确保数值在0~255范围内
            }
            return sb.toString();
        } catch (IOException | NoSuchAlgorithmException e) {
            throw new RuntimeException("MD5计算失败", e);
        }
    }*/

    public static String calculateMD5(InputStream in) {

        try (InputStream is =  in) {
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] buffer = new byte[8192];
            int read;
            while ((read = is.read(buffer)) != -1) {
                md.update(buffer, 0, read);
            }
            byte[] hashBytes = md.digest();
            StringBuilder sb = new StringBuilder();
            for (byte b : hashBytes) {
                sb.append(String.format("%02x", b & 0xFF));  // 确保数值在0~255范围内
            }
            return sb.toString();
        } catch (IOException | NoSuchAlgorithmException e) {
            throw new RuntimeException("MD5计算失败", e);
        }
    }

    public static void DeleteFolderContents ( Path dir) {

        if (Files.exists(dir)) {
            try (var paths = Files.walk(dir)) {
                paths
                        .sorted(Comparator.reverseOrder()) // 先处理子文件和子目录
                        .filter(path -> !path.equals(dir)) // 排除根目录本身
                        .forEach(path -> {
                            try {
                                Files.delete(path);
                                System.out.println("已删除: " + path);
                            } catch (IOException e) {
                                System.err.println("无法删除 " + path + ": " + e.getMessage());
                            }
                        });
                Files.deleteIfExists(dir);
                System.out.println("所有内容已成功删除。");
            } catch (IOException e) {
                System.err.println("遍历目录时出错: " + e.getMessage());
            }
        } else {
            System.out.println("目录不存在，无需删除。");
        }

    }

}
